package com.hzxgs.tracelogstarter.config;

import com.hzxgs.tracelogstarter.trace.RabbitMQAfterReceiveMessagePostProcessor;
import com.hzxgs.tracelogstarter.trace.RabbitMQBeforeSendReplyPostProcessor;
import org.springframework.amqp.rabbit.config.ContainerCustomizer;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.amqp.RabbitTemplateConfigurer;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@ConditionalOnClass(value = {RabbitTemplate.class})
public class RabbitTemplateConfig {

    @Resource
    private RabbitMQBeforeSendReplyPostProcessor rabbitMQBeforeSendReplyPostProcessor;
    @Resource
    private RabbitMQAfterReceiveMessagePostProcessor rabbitMQAfterReceiveMessagePostProcessor;

    @Bean
    public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate();
        configurer.configure(template, connectionFactory);

        template.setBeforePublishPostProcessors(rabbitMQBeforeSendReplyPostProcessor);
        template.setMandatory(true);

        return template;
    }

    @Bean(name = {"rabbitListenerContainerFactory"})
    @ConditionalOnProperty(
            prefix = "spring.rabbitmq.listener",
            name = {"type"},
            havingValue = "simple",
            matchIfMissing = true
    )
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory,
            ObjectProvider<ContainerCustomizer<SimpleMessageListenerContainer>> simpleContainerCustomizer) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        simpleContainerCustomizer.ifUnique(factory::setContainerCustomizer);

        factory.setAfterReceivePostProcessors(rabbitMQAfterReceiveMessagePostProcessor);

        return factory;
    }
}
